#include "woptions/options.h"
#include "test.h"

namespace {

struct MyObject
{
	MyObject() : value(0) {}

	void SetValue(int to)
	{
		value = to;
	}

	int value;
};

int gMyFunctionValue = 0;

void MyFunction(int arg)
{
	gMyFunctionValue = arg;
}

} // namespace

BOOST_AUTO_TEST_CASE( test_bind_argument_ignore )
{
	woptions::Options opts;
	opts.argument("desc",woptions::bind_argument_ignore());
	
	std::vector<std::string> args(1);
	BOOST_CHECK_NO_THROW( opts.parse(args) );
}

BOOST_AUTO_TEST_CASE( test_bind_argument_var )
{
	int         ivalue=0;
	float       fvalue=0;
	std::string svalue="";
	
	woptions::Options opts;
	opts.argument("desc",woptions::bind_argument_var(ivalue));
	opts.argument("desc",woptions::bind_argument_var(fvalue));
	opts.argument("desc",woptions::bind_argument_var(svalue));
	
	std::vector<std::string> args;
	args.push_back( "1" );
	args.push_back( "1.5" );
	args.push_back( "string" );
	
	BOOST_CHECK_NO_THROW( opts.parse(args) );
	BOOST_CHECK_EQUAL( ivalue, 1 );
	BOOST_CHECK_EQUAL( fvalue, 1.5f );
	BOOST_CHECK_EQUAL( svalue, "string" );
	
	args[0] = "1.5";
	BOOST_CHECK_THROW( opts.parse(args), woptions::ArgumentException );
}

BOOST_AUTO_TEST_CASE( test_bind_argument_fun )
{
	woptions::Options opts;
	opts.argument("desc",woptions::bind_argument_fun(MyFunction));
	
	std::vector<std::string> args;
	args.push_back( "1" );
	
	BOOST_CHECK_NO_THROW( opts.parse(args) );
	BOOST_CHECK_EQUAL( gMyFunctionValue, 1 );
}

BOOST_AUTO_TEST_CASE( test_bind_argument_mem_fun )
{
	MyObject o;

	woptions::Options opts;
	opts.argument("desc",woptions::bind_argument_mem_fun(&o,&MyObject::SetValue));
	
	std::vector<std::string> args;
	args.push_back( "1" );
	
	BOOST_CHECK_NO_THROW( opts.parse(args) );
	BOOST_CHECK_EQUAL( o.value, 1 );
}
